package org.intelligentsia.temporal.primitives;

import java.io.Serializable;

import org.intelligentsia.temporal.Temporal;
import org.intelligentsia.temporal.TransactionTime;

/**
 * BaseTemporal implement a Temporal as a pair of {TransactionTime, T}.
 * 
 * @author <a href="mailto:jguibert@intelligents-ia.com" >Jerome Guibert</a>
 * 
 */
public abstract class BaseTemporal<T> implements Temporal, Serializable {

	private static final long	serialVersionUID	= -8025775763842469585L;
	private TransactionTime		transactionTime;
	protected T					value;

	public BaseTemporal() {
		super();
		transactionTime = new TransactionTime();
		value = null;
	}

	public BaseTemporal(final TransactionTime transactionTime, final T value) {
		super();
		this.transactionTime = transactionTime;
		this.value = value;
	}

	@Override
	public final TransactionTime getTransactionTime() {
		return transactionTime;
	}

	@Override
	public final void setTransactionTime(final TransactionTime transactionTime) {
		this.transactionTime = transactionTime;
	}

	public abstract T getValue();

	public void setValue(final T value) {
		this.value = value;
	}

	@Override
	public String toString() {
		return "[transactionTime=" + transactionTime + ", value=" + value + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.transactionTime == null) ? 0 : this.transactionTime.hashCode());
		result = prime * result + ((this.value == null) ? 0 : this.value.hashCode());
		return result;
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		@SuppressWarnings("rawtypes")
		final BaseTemporal other = (BaseTemporal) obj;
		if (this.transactionTime == null) {
			if (other.transactionTime != null) {
				return false;
			}
		} else if (!this.transactionTime.equals(other.transactionTime)) {
			return false;
		}
		if (this.value == null) {
			if (other.value != null) {
				return false;
			}
		} else if (!this.value.equals(other.value)) {
			return false;
		}
		return true;
	}

}
